//
// RS Game Framework
// Copyright © 2009 Jedd Haberstro
// jhaberstro@gmail.com
// 
// $Id:
//

#ifndef RS_ANYFXNPOINTER_HPP
#define RS_ANYFXNPOINTER_HPP

#include "rs/MetaFacilities.hpp"

namespace rs
{
    namespace internal
    {
        typedef void generic_fxn();

        class alignment_dummy_base1 { };
        class alignment_dummy_base2 { };

        class alignment_dummy_s : alignment_dummy_base1 { };                         
        // single inheritance.

        class alignment_dummy_m : alignment_dummy_base1, alignment_dummy_base2 { };  
        // multiple inheritance.

        class alignment_dummy_v : virtual alignment_dummy_base1 { };                 
        // virtual inheritance.

        class alignment_dummy_u;                                                     
        // unknown (incomplete).


        typedef void (alignment_dummy_s::*mfn_ptr_s)();  
        // member function pointer of single inheritance class.

        typedef void (alignment_dummy_m::*mfn_ptr_m)();  
        // member function pointer of multiple inheritance class.

        typedef void (alignment_dummy_v::*mfn_ptr_v)();  
        // member function pointer of virtual inheritance class.

        typedef void (alignment_dummy_u::*mfn_ptr_u)();  
        // member function pointer of unknown (incomplete) class.


        typedef void (alignment_dummy_m::*generic_mfn_ptr)();

        union max_align_for_funtion_pointer
        {
            void const * dummy_vp;
            generic_fxn * dummy_fp;
            rs::meta::If< (sizeof(generic_mfn_ptr) < sizeof(mfn_ptr_s)),
                generic_mfn_ptr, mfn_ptr_s >::Result dummy_mfp1;
            rs::meta::If< (sizeof(generic_mfn_ptr) < sizeof(mfn_ptr_m)),
                generic_mfn_ptr, mfn_ptr_m >::Result dummy_mfp2;
            rs::meta::If< (sizeof(generic_mfn_ptr) < sizeof(mfn_ptr_v)),
                generic_mfn_ptr, mfn_ptr_v >::Result dummy_mfp3;
            rs::meta::If< (sizeof(generic_mfn_ptr) < sizeof(mfn_ptr_u)),
                generic_mfn_ptr, mfn_ptr_u >::Result dummy_mfp4;
        };

        //BOOST_STATIC_CONSTANT( unsigned, 
        //    any_fxn_size = sizeof( max_align_for_funtion_pointer ) );
        static const unsigned any_fxn_size = sizeof(max_align_for_funtion_pointer);

        union any_fxn_pointer
        {
            void const * obj_ptr;
            generic_fxn * fxn_ptr;
            generic_mfn_ptr mfn_ptr;
            max_align_for_funtion_pointer m_;
        };
    }
}

#endif // RS_ANYFXNPOINTER_HPP
